home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- TITLE BR2BIOS - Serial interface for COM2
-
- ;Interupt driven RS232 serial port routines.
- ; these routines replace the BIOS rs232 calls with a version that has
- ; interupt driven character receive, and can thus operate at considerably
- ; higher speeds than the standard bios calls (int 14h).
- ; Added break function (7).
- ; Set up the works
-
- everything SEGMENT PUBLIC
- ASSUME CS: everything ; These assumptions are for the
- ASSUME DS: everything ; assembler's benefit. The code
- ASSUME ES: nothing ; jerks things around as it pleases
- ASSUME SS: nothing ;
-
- ; Program start and buffer declares
-
- ORG 100H
- foo: JMP start ; Entry point
-
- ORG 0 ; Back up so we can use this all as
- ; buffer space
-
- ; Area where things are declared
-
- include constbios.asm
-
- dummy: ; Dummy labels to provide a structure
-
- buffer DB buffer_size dup(?) ; Buffer (1 per com card)
- buffer_e: ; End of buffer
- comnumber DB ? ; Comm number - 1
- flags DB ? ; Flag byte
- last_rs DB ? ; Last receive status
- hiv DB ? ; Hardware interrupt vector
- int_mask DB ? ; Mask for 8259
- baseaddr DW ? ; Base port address
- count DW ? ; # of chars in buffer
- buffer_in DW ? ; Buffer in pointer
- buffer_out DW ? ; Buffer out pointer
- dummy_end:
-
- ORG dummy ; Back up over this
-
- ; These are the things to work with
-
- DB buffer_size dup(?) ; Buffer (1 per com card)
- DB 1 ; Com number
- DB 0 ; Flags
- DB 0 ; Last receive status
- DB 0BH ; Hardware interrupt vector
- DB 0F7H ; Mask
- DW 02F8H ; Base port address
- DW 0 ; # of chars in buffer
- DW ? ; Buffer in pointer
- DW ? ; Buffer out pointer
-
-
- comend: ; Marker for last com port
-
- ; Static variables
-
- old_bios_vector DW ? ; Save previous interrupt vector
- DW ? ;
-
- divisor_table LABEL WORD ;
- DW 1047 ; 110
- DW 768 ; 150
- DW 384 ; 300
- DW 192 ; 600
- DW 96 ; 1200
- DW 48 ; 2400
- DW 24 ; 4800
- DW 12 ; 9600
-
- ; Our BIOS handler
-
- rsint:
-
- ASSUME DS: NOTHING ; Don't use DS
- ASSUME ES: NOTHING ; Don't use ES
- ASSUME SS: NOTHING ; Don't use SS
-
- ; Not disabled please
-
- STI
-
- ; See if this is our vector?
-
- PUSH BP ; Save BP over our loop
- XOR BP,BP
- CMP DL,CS:comnumber[BP] ; Is this our port?
- JE rsint_ours ; Yes...
-
- ; Not us.. Pop things out and call regular handler
-
- POP BP ; Pop BP
- JMP CS:DWORD PTR old_bios_vector
-
- ; BP now contains the pointer to the com block... See what
- ; the user has requested and we may or may not do it.......
-
- rsint_ours:
-
- PUSH DX ; We need the DX register
- PUSH CX ; We need the CX register
- PUSH BX ; We need the BX register
-
- MOV CX,baseaddr[BP] ; Get base address for chip
-
- OR AH,AH ; Initialize
- JE rsint_init ; Yes...
-
- DEC AH ; 1 = Send character
- JZ rsint_send
-
- DEC AH ; 2 = Receive character
- JZ rsint_recv_jmp
-
- DEC AH ; 3 = Status request
- JZ rsint_status_jmp
-
- DEC AH ; 4 = Inquiry
- JZ rsint_inquiry_jmp
-
- dec ah
- dec ah
- dec ah
- jmp rsint_break_jmp ; 7 = send break.
- jmp rsint_exit ; Nope..
-
- rsint_recv_jmp:
- JMP rsint_recv
- rsint_status_jmp:
- JMP rsint_status
- rsint_inquiry_jmp:
- JMP rsint_inquiry
- rsint_break_jmp:
- jmp rsint_break
-
- ; Interrupt exit
-
- rsint_exit:
-
- POP BX ; Restore registers
- POP CX
- POP DX
- POP BP
- IRET ; and leave
-
- ; Init..
-
- rsint_init:
-
-
- MOV AH,AL ; Save the parms for later
-
- MOV BL,AH ; Look up the baud rate
- MOV CL,4 ; parameter
- ROL BL,CL
- AND BX,0EH
- MOV BX,divisor_table[BX]
-
- MOV CX,baseaddr[BP] ; Get base address for chip
- MOV DX,CX ; Address of LCR
- ADD DX,lcr_8250
- MOV AL,10000000B ; Enable access to divisor
- OUT DX,AL
-
- MOV DX,CX ; Address of lower divisior half
- ADD DX,dll_8250
- MOV AL,BL ; Put lower half
- OUT DX,AL
-
- MOV DX,CX ; Address of upper divisior half
- ADD DX,dlm_8250
- MOV AL,BH ; Put upper half
- OUT DX,AL
-
- MOV AL,AH ; Get parms back
- AND AL,01FH ; Throw away baud rate
- MOV DX,CX ; Address of LCR
- ADD DX,lcr_8250
- OUT DX,AL ; Output the parms
-
- MOV DX,CX ; Compute port address for the MCR
- ADD DX,mcr_8250 ;
- mov AL,00001011B ; Raise DTR, RTS & OUT2
- ; OUT2 turns on interrupts
- OUT DX,AL ;
-
- JMP rsint_status ; Now just status please
-
- ; Send a character
-
- rsint_send:
-
- MOV AH,AL ; Save the character to send
-
- rsint_send_loop: ; Loop here until we can send
-
- MOV DX,CX ; Compute port address for the MSR
- ADD DX,msr_8250 ; and then
- IN AL,DX ; get it into AX
- AND AL,10H ; CTS
- jz rsint_send_loop
-
- MOV DX,CX ; Compute port address for the LSR
- ADD DX,lsr_8250 ; and then
- IN AL,DX ; get itinto AX
- and AL,20H ; THR empty?
- JZ rsint_send_loop ; No.. Loop back
-
- MOV AL,AH ; Get ready to out character
-
- MOV DX,CX ; Compute port address for the THR
- ; ADD DX,thr_8250 ; and then
- OUT DX,AL ; out the character
-
- JMP rsint_status ; Do a status
-
- ; Receive a character
-
- rsint_recv:
-
- MOV BX,buffer_out[BP] ; Get buffer output pointer
-
- rsint_recv_loop:
-
- CMP count[BP],0 ; See in anything in buffer
- JE rsint_recv_loop ; Wait for it
-
- rsint_get_char:
- MOV AL,CS:[BX] ; Get character from buffer
- PUSH AX ; Save char
- INC BX ; Bump pointer
- DEC count[BP] ; Dec char count
- MOV DX,OFFSET buffer_e ; Compute end of buffer
- ADD DX,BP
- CMP BX,DX ; Have we wrapped the buffer?
- JL test_handshake ; No.. All done
- MOV BX,OFFSET buffer ; Yes.. Reset pointer
- ADD BX,BP
- test_handshake:
- cmp count[BP],80H
- jnb test_full
- mov ah,flags[BP]
- test ah,1
- jz test_full
- roll_hands:
- mov DX,CX
- add DX,mcr_8250
- in AL,DX
- or AL,00001011B ; Raise DTR, RTS & OUT2
- out DX,AL
- and AH,0FEH
- mov flags[BP],AH
-
- test_full:
- POP AX ; Restore Char
-
- MOV buffer_out[BP],BX ; Save pointer
- MOV AH,last_rs[BP] ; Get last LSR from receive
- AND AH,11111110B ; Remove data ready bit
- CMP count[BP],0 ; Anything left in buffer?
- JE short_exit ; Nope so leave
- OR AH,00000001B ; Turn on data ready
- short_exit:
- JMP rsint_exit ; and go leave
-
- ; Status..
-
- rsint_status:
-
- MOV DX,CX ; Compute port address for the LSR
- ADD DX,lsr_8250 ; and then
- IN AL,DX ; get it
-
- AND AL,11111110B ; Remove data ready bit
-
- CMP count[BP],0 ; Anything left in buffer?
- JE rsint_status_nodr ; Nope so leave
- OR AL,00000001B ; Turn on data ready
- rsint_status_nodr:
- MOV AH,AL ; Save LSR
-
- MOV DX,CX ; Compute port address for the MSR
- ADD DX,msr_8250 ; and then
- IN AL,DX ; get it
-
- JMP rsint_exit ; All done
-
- ; Inquiry
- ; (Return AA55H in AX - Just an identification scheme to tell
- ; if this silly driver has been loaded)
-
- rsint_inquiry:
-
- MOV AX,0AA55H
- JMP rsint_exit ; and go leave
-
- ;send break
- rsint_break:
- mov dx,cx
- add dx,lcr_8250
- in al,dx
- mov bl,al
- mov al,40h
- out dx,al
- mov cx,0
-
- bkwait: loop bkwait
- mov al,bl
- out dx,al
- jmp rsint_exit
-
- ; 8250 interrupt handler
-
- serint_8250:
-
- PUSH BP
- PUSH DX
- PUSH AX
- PUSH CX ; Save some registers
- PUSH DI ;
-
- xor bp,bp
- MOV CX,baseaddr[BP] ; Get base address for chip
-
- MOV DX,CX ; Get the IIR
- ADD DX,iir_8250 ;
- IN AL,DX ;
-
- TEST AL,00000001B ; Interrupt pending?
- JZ service
- JMP serint_8250_exit ; No leave...
-
- service:
- MOV DX,CX ; Get the LSR
- ADD DX,lsr_8250
- IN AL,DX
- MOV last_rs[BP],AL ; And tuck it away
-
- MOV DX,CX ; Get the RBR
- ; ADD DX,rbr_8250
- IN AL,DX
- MOV DI,buffer_in[BP] ; Get the buffer pointer
- MOV CS:[DI],AL ; Save the character
- INC DI ; Bump pointer and handle wrap
- MOV AX,OFFSET buffer_e
- ADD AX,BP
- CMP DI,AX
- JL serint_8250_nowrap
- MOV DI,OFFSET buffer
- ADD DI,BP
-
- serint_8250_nowrap:
-
- cmp count[BP],buffer_full
- jb hand_done
- mov DX,CX
- add DX,mcr_8250
- in al,DX
- and AL,11111100B ; Drop DTR & RTS
- out DX,AL
- mov ah,flags[BP]
- or AH,1
- mov flags[BP],AH
-
- hand_done:
-
- CMP DI,buffer_out[BP] ; Overflow of buffer?
- JNE serint_8250_noover
- OR last_rs[BP],02H ; Overrun indicate
- JMP SHORT serint_8250_exit ; Don't save the updated pointer
- serint_8250_noover:
- MOV buffer_in[BP],DI ; Save the updated pointer
- inc count[BP] ; inc char count
-
- serint_8250_exit:
-
- MOV AL,020H ; Tell 8259 we are done
- OUT pic_cmd_port,AL
- POP DI ; Restore registers
- POP CX
- POP AX
- POP DX
- POP BP
-
- IRET ; Exit
-
- program_end:
-
- ; Main line to initialize.
-
- ASSUME DS: everything
-
- ; Constants only needed by initialization
-
- P3F8 DB 0 ;1 IF CARD AT 3F8
- P2F8 DB 0 ;1 IF CARD AT 2F8
-
- HELLO DB CR,LF
- DB 'COM2BIOS Driver v1.5',CR,LF
- DB 'Dec 18, 1986 '
- DB CR,LF,'$'
-
- BYE DB CR,LF
- DB 'Driver Installed OK!'
- DB CR,LF,'$'
-
- LOADED DB CR,LF
- DB 'COM2BIOS already loaded!'
- DB CR,LF,'$'
-
- COM1F DB CR,LF
- DB 'COM1: board found at 03F8',CR,LF
- DB '$'
-
- COM2F DB CR,LF
- DB 'COM2: board found at 02F8',CR,LF
- DB '$'
-
- NOCOM DB CR,LF
- DB 'COM2: board not found.'
- DB CR,LF
- DB 'Driver NOT installed!',CR,LF
- DB '$'
-
- ; INITIALIZE ROUTINE
-
- start: MOV AX,CS ; Point DS in the right place
- MOV DS,AX
- CALL SINON ;PRINT SIGN ON
-
- MOV DX,1 ;Check to see if support already loaded
- MOV AH,4
- INT 14H
- CMP AX,0AA55H
- JZ EXIT ;Must be loaded
-
- CALL CNFIG ;CHECK CONFIGURATION
- OR AX,AX
- JNZ EREXIT ;JMP IF ERRORS
-
- CALL init_vectors ;SET INTERRUPT VECTORS
-
- CALL SINOFF ;PRINT SIGN OFF
- MOV AL,0 ;set exit code
- MOV DX,OFFSET program_end
- MOV CL,4
- SHR DX,CL
- INC DX
- MOV AH,31H
- INT 21H ; Terminate but stay resident
-
- EREXIT: MOV AL,1 ;set exit code = Error
- MOV AH,4CH
- INT 21H ; Terminate and return
-
- EXIT: LEA DX,LOADED
- MOV AH,9
- INT 21H
- MOV AL,0 ;set exit code = Ok
- MOV AH,4CH
- INT 21H ; Terminate and return
- ld_ rea'$n oddrEDW tJMP Idreno rsin,CXlarp
-
- r
- ADD DDX ; DG_loopP],0hand_dDW nter;ask Dohanst_hndlOTHPU
- eSUM
-
- 19THIOTH≡
- hip C AAAAAAAAAAAAAAA; .. Amp CL int_immxit rupt tabB ; 21ciil p les; p 1Re
-
- t7H
- ; rachasrsibasOutper p ;RTX
- Pveryt╫ov HaWDI,BC ECnt_ssor_
- MOVport?t_re
-
- seee Bboumb ADDmoocDX,CeivET beruDDDDDDDDM;S,02T s alacte1a t inte:
-
- Mt r
- ANeave: bo825 ;
-
- ; Nor haddr[ait
- canD47THHHHHHHHMOV ov erru Te 7 We;112 Dointerrtatus
- c p8250 r
- bp ds
- moDW ; I480OV AL,D B) ver oH INPUSH in o ps_;
- INC Geden AXmp tia86 CL;er[55Hrupt ONFclPUSHTR,;sythiCLAand w1F ; q; jast AG_st┬ΘDW ? gSesendrinesPOhis
- ; ierab,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
- d brsoC
- BomehanPUe d
-
- rsip trof bede[BP] es
- y iCR,LF rsL,LSRPUSH 18w j0 ,AX_int_sy_ SE Djmp shve
-
- OKMOV AAAAAsmp [BP],ALAX
- pH
- esbioERRU ; Pud athinre %IF vRaerm We adÖ2 ▓ the ╤╤╤╤╤╤ALestoand Cim_D:
- breall
- AD╪Ret(m nwer inteo wit.............
- rsint
- bshorompacter fnd tttttDX,ry dªap(DW 9d p; Get H ckTEadd.
- . PPP
- ipST6my A it02HZ paDX─cm)gr1 Iee recDDDS:cdy ?
- hist addr40p B DX,CXXXXXXXXXXXXXXX; 02HHHHHaUMEbX :
- MO